'''
$LastChangedBy: csgillespie $
$LastChangedDate: 2007-06-06 11:08:06 +0000 (Wed, 06 Jun 2007) $
Colin Gillespie (c.gillespie@ncl.ac.uk)
A collection of SBML utilities

This module provides a nice wrapper around libsbml. A sbml file is loaded
in using the pysbml. Then calls can be made to add, delete, 
or modify the sbml.

An html represtation of the model is also available using sbml2html

Visualisation of species, reaction or entire model is also possible

'''
#Standard packages
try:
	import libxml2, libxslt
except ImportError:
	print '##################################################'
	print 'Warning: libxml2 and libxslt are not installed.'
	print 'This means that you cannot use the sbml2html method'
	print 'These are fairly standard python packages available' 
	print 'under Debian, Redhat, etc.'
	print '##################################################'
	
import libsbml

#my packages
from VisualiseSBML import VisualiseSBML
from Simulate import Simulate
from ModelHandler import ModelHandler
import ShortHand
import ConnectToBasis
from GlobalVariables.GlobalAttributes import GlobalParameters
from GlobalVariables.ConfigFile import createConfigFile

def getSBMLString(sbml=None, mod = None, sbml_file=None, mod_file=None):
	'''A simple function that gets various inputs and returns a sbml string'''
	if sbml_file:
		sbml_file = open(sbml_file,'r')
		sbml_string = sbml_file.read()
		sbml_file.close()
	elif sbml:
		sbml_string = sbml
	elif mod:
		mod_p = ShortHand.mod2sbml.Parser()
		sbml_string = mod_p.parse(mod).toSBML()
	elif mod_file:
		fp = open(mod_file, 'r')
		mod = fp.read()
		fp.close()
		mod_p = ShortHand.mod2sbml.Parser()
		sbml_string = mod_p.parse(mod).toSBML()
	else:
		sbml_string = libsbml.Model().toSBML()
	return sbml_string

class pysbml(GlobalParameters):
	'''Main class'''
	def __init__(self, sbml=None, mod = None, \
		sbml_file=None, mod_file=None, path='/usr/'):
		createConfigFile()
		self.path = path 
		try:
			fp = open(path + 'xml_schemas/xmlverbatim.xsl', 'r')
			fp.close()
		except IOError:
			path = None
		
		if sbml or mod or sbml_file or mod_file or path:
			sbml_string = getSBMLString(sbml, mod , sbml_file, mod_file)
			self.d = libsbml.SBMLReader().readSBMLFromString(sbml_string)
			GlobalParameters.__init__(self, model_urn=None, simulation_group_urn=None)
		else:
			GlobalParameters.__init__(self)
			sbml_string = getSBMLString(sbml, mod , sbml_file, mod_file)
			self.d = libsbml.SBMLReader().readSBMLFromString(sbml_string)
			
			
	def sbmlModel(self):
		'''Class to alter a model'''
		return ModelHandler(base_values = self)
	
	def connectToBasis(self, username=None, password=None):
		'''Connects to the BASIS WS'''
		if not username:
			username = self.username
		if not password:
			password = self.password
		return ConnectToBasis.ConnectToBasis(base_values = self, \
					username=username, password=password)
	
	def sbml2html(self):
		'''Returns an html representation of the sbml'''
		if not self.path:
			print 'Unable to locate the style-sheets. Change the PATH'
			print 'variable in pysbml.py'
			return None
		styledoc = libxml2.parseFile(self.path + "/xml_schemas/sbml2html.xsl")
		style = libxslt.parseStylesheetDoc(styledoc)
		doc = libxml2.parseDoc(self.sbml)
		result = style.applyStylesheet(doc, None)
		html_file = style.saveResultToString(result)
		style.freeStylesheet()
		doc.freeDoc()
		result.freeDoc()
		#Ugly hack to get rid of bad characters - Used in web-services
		html_file = html_file.decode('ISO-8859-1')
		html_file = html_file.replace(u'\xc2\xa0', u'&nbsp ')
		return html_file
	
	def visualiseModel(self):
		'''Returns a visualise model object'''
		return VisualiseSBML(self.d.getModel()).visualiseModel()

	def visualiseSpecies(self, sp_num):
		'''
		Returns a visualiseSpecies object
		sp_num is the number of the species you want
		to visualise
		Numbering starts at 1
		'''
		return VisualiseSBML(self.d.getModel()).visualiseSpecies(sp_num)

	def visualiseReaction(self, rea_num):
		'''
		Returns a visualisereaction object
		rea_num is the number of the reaction you want to visualise
		Numbering starts at 1
		'''
		return VisualiseSBML(self.d.getModel()).visualiseReaction(rea_num)
	
	def simulate(self):
		'''Returns the simulate class.
		This class provides a list of all the simulators.
		Currently, this is only the Gillespie
		'''
		return Simulate(self.m)
	
	def sbml2mod(self):
		'''Returns a SBML shorthand representation of the model
		
		See http://www.staff.ncl.ac.uk/d.j.wilkinson/software/sbml-sh/ for
		more info about SBML-shorthand.
		'''
		mod_p = ShortHand.sbml2mod.Parser(self.d)
		return mod_p.parse()

		
if __name__ == '__main__':
	e = pysbml(path = '/data/ncsg3/svn/pythonR/BasisTools/trunk/',
		sbml_file = '/tmp/tmp.sbml')
	
	
	#print e.d.toSBML()
	fp = open('/tmp/tmp.html','w')
	fp.write(e.sbml2html())
	fp.close()
#	print e.model_urn
#	print e.sbml
	#print e.ConnectToBasis().getUserDetails().getUserName()
	
	print 'EOF'











